package com.itjin.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.itjin.model.domain.entity.Post;
import com.itjin.model.domain.entity.User;
import com.itjin.model.domain.dto.SendMessageDTO;
import com.itjin.service.ContentAuditService;
import com.itjin.service.PostService;
import com.itjin.service.MessageService;
import com.itjin.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 内容审核服务实现
 */
@Service
public class ContentAuditServiceImpl implements ContentAuditService {

    private static final Logger log = LoggerFactory.getLogger(ContentAuditServiceImpl.class);

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    @Qualifier("auditRedisTemplate")
    private RedisTemplate<String, String> auditRedisTemplate;
    
    @Autowired
    private PostService postService;
    
    @Autowired
    private MessageService messageService;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private ObjectMapper objectMapper;
    
    private ExecutorService executorService;
    private volatile boolean isListening = false;
    
    // 队列名称
    private static final String AUDIT_QUEUE = "content_audit_queue";
    private static final String RESULT_QUEUE = "audit_result_queue";
    
    @PostConstruct
    public void init() {
        executorService = Executors.newSingleThreadExecutor();
        startAuditResultListener();
    }
    
    @PreDestroy
    public void destroy() {
        stopAuditResultListener();
        if (executorService != null) {
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }
    
    @Override
    public boolean sendPostForAudit(Post post) {
        try {
            // 构建审核请求数据
            Map<String, Object> auditRequest = new HashMap<>();
            auditRequest.put("post_id", post.getId());
            auditRequest.put("content", post.getContent());
            auditRequest.put("title", post.getTitle());
            auditRequest.put("author_id", post.getAuthorId());
            auditRequest.put("timestamp", new Date().toInstant().toString());

            // 添加图片URL列表
            List<String> images = new ArrayList<>();
            if (post.getImage1() != null) images.add(post.getImage1());
            if (post.getImage2() != null) images.add(post.getImage2());
            if (post.getImage3() != null) images.add(post.getImage3());
            if (post.getImage4() != null) images.add(post.getImage4());
            if (post.getImage5() != null) images.add(post.getImage5());
            if (post.getImage6() != null) images.add(post.getImage6());
            if (post.getImage7() != null) images.add(post.getImage7());
            if (post.getImage8() != null) images.add(post.getImage8());
            if (post.getImage9() != null) images.add(post.getImage9());
            auditRequest.put("images", images);

            // 发送到审核队列
            redisTemplate.opsForList().leftPush(AUDIT_QUEUE, auditRequest);

            log.info("帖子已发送到审核队列: postId={}", post.getId());
            return true;

        } catch (Exception e) {
            log.error("发送帖子到审核队列失败: postId={}, error={}", post.getId(), e.getMessage());
            return false;
        }
    }
    
    @Override
    public boolean handleAuditResult(String auditResultJson) {
        try {
            log.info("收到审核结果: {}", auditResultJson);

            // 创建一个新的ObjectMapper，不使用类型信息
            ObjectMapper simpleMapper = new ObjectMapper();

            // 解析审核结果
            Map<String, Object> auditResult = simpleMapper.readValue(auditResultJson, Map.class);
            
            Integer postId = (Integer) auditResult.get("post_id");
            String result = (String) auditResult.get("audit_result");
            Double confidence = (Double) auditResult.get("confidence");
            List<String> reasons = (List<String>) auditResult.get("reasons");
            
            log.info("收到审核结果: postId={}, result={}, confidence={}", postId, result, confidence);
            
            // 根据审核结果处理帖子
            switch (result) {
                case "PASS":
                    return handlePassResult(postId);
                case "REJECT":
                    return handleRejectResult(postId, reasons);
                case "MANUAL":
                    return handleManualResult(postId, reasons);
                default:
                    log.warn("未知的审核结果: {}", result);
                    return false;
            }
            
        } catch (Exception e) {
            log.error("处理审核结果失败: {}", e.getMessage());
            return false;
        }
    }
    
    private boolean handlePassResult(Integer postId) {
        try {
            // 更新帖子状态为已发布
            boolean success = postService.approvePost(postId, 666); // 使用系统管理员ID
            
            if (success) {
                log.info("帖子审核通过，已自动发布: postId={}", postId);
            }
            
            return success;
            
        } catch (Exception e) {
            log.error("处理审核通过结果失败: postId={}, error={}", postId, e.getMessage());
            return false;
        }
    }
    
    private boolean handleRejectResult(Integer postId, List<String> reasons) {
        try {
            String reasonText = reasons != null && !reasons.isEmpty()
                ? String.join(", ", reasons)
                : "内容不符合社区规范";

            // AI审核拒绝帖子，设置状态为5（已拒绝）
            boolean success = rejectPostByAI(postId, "AI自动审核: " + reasonText);

            if (success) {
                log.info("帖子AI审核不通过，已自动拒绝: postId={}, reasons={}", postId, reasonText);
            }

            return success;

        } catch (Exception e) {
            log.error("处理AI审核拒绝结果失败: postId={}, error={}", postId, e.getMessage());
            return false;
        }
    }
    
    private boolean handleManualResult(Integer postId, List<String> reasons) {
        try {
            // 需要人工审核的帖子，设置状态为1（人工审核中）
            String reasonText = reasons != null && !reasons.isEmpty()
                ? String.join(", ", reasons)
                : "需要人工审核";

            // 更新帖子状态为人工审核中
            boolean success = setPostToManualReview(postId, reasonText);

            if (success) {
                log.info("帖子转入人工审核: postId={}, reasons={}", postId, reasonText);
            }

            return success;

        } catch (Exception e) {
            log.error("处理人工审核结果失败: postId={}, error={}", postId, e.getMessage());
            return false;
        }
    }

    /**
     * AI审核拒绝帖子，设置状态为5（已拒绝）
     */
    private boolean rejectPostByAI(Integer postId, String reason) {
        try {
            // 直接更新帖子状态为5（已拒绝），不使用原有的rejectPost方法
            // 因为原有方法只接受状态为1的帖子，而我们的帖子状态是4（AI审查中）

            // 1. 获取帖子信息
            Post post = postService.getById(postId);
            if (post == null) {
                log.error("帖子不存在: postId={}", postId);
                return false;
            }

            // 2. 直接更新状态为5（已拒绝）
            boolean updated = postService.update(null,
                new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<Post>()
                    .eq("id", postId)
                    .set("postStatus", 5)
                    .set("updateTime", new Date())
            );

            if (!updated) {
                log.error("更新帖子状态失败: postId={}, status=5", postId);
                return false;
            }

            log.info("AI审核拒绝帖子成功: postId={}, reason={}", postId, reason);

            // 3. 发送通知给作者
            try {
                User author = userMapper.selectById(post.getAuthorId());
                if (author != null) {
                    // 构建消息内容
                    String messageContent = String.format(
                        "您的帖子《%s》未通过AI自动审核。原因：%s",
                        post.getTitle() != null && !post.getTitle().isEmpty() ? post.getTitle() : "无标题",
                        reason.trim());

                    // 创建消息DTO
                    SendMessageDTO messageDTO = new SendMessageDTO();
                    messageDTO.setReceiverId(post.getAuthorId());
                    messageDTO.setContent(messageContent);
                    messageDTO.setMessageType(1); // 系统消息类型

                    // 发送消息
                    messageService.sendMessage(666, messageDTO); // 使用系统管理员ID 666

                    log.info("已发送AI审核拒绝通知给用户: userId={}", post.getAuthorId());

                    // 4. 更新作者的发帖数（因为帖子被拒绝）
                    if (author.getMyPublish() > 0) {
                        User updateAuthor = new User();
                        updateAuthor.setId(author.getId());
                        updateAuthor.setMyPublish(author.getMyPublish() - 1);
                        userMapper.updateById(updateAuthor);
                        log.info("已更新作者发帖数: userId={}, newCount={}", author.getId(), author.getMyPublish() - 1);
                    }
                }
            } catch (Exception e) {
                log.error("发送AI审核拒绝通知失败: postId={}, error={}", postId, e.getMessage());
                // 不影响主流程，继续执行
            }

            return true;

        } catch (Exception e) {
            log.error("AI拒绝帖子失败: postId={}, error={}", postId, e.getMessage());
            return false;
        }
    }

    /**
     * 设置帖子为人工审核状态
     */
    private boolean setPostToManualReview(Integer postId, String reason) {
        try {
            // 使用UpdateWrapper直接更新状态为1（人工审核中）
            boolean updated = postService.update(null,
                new com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper<Post>()
                    .eq("id", postId)
                    .set("postStatus", 1)
                    .set("updateTime", new Date())
            );

            if (updated) {
                log.info("设置帖子为人工审核完成: postId={}, reason={}", postId, reason);

                // TODO: 发送通知给作者（暂时跳过，避免Lombok问题）
                // 后续可以在PostService中添加专门的方法来处理通知

            } else {
                log.error("更新帖子状态失败: postId={}, status=1", postId);
            }

            return updated;

        } catch (Exception e) {
            log.error("设置帖子为人工审核失败: postId={}, error={}", postId, e.getMessage());
            return false;
        }
    }
    
    @Override
    public void startAuditResultListener() {
        if (isListening) {
            return;
        }
        
        isListening = true;
        executorService.submit(() -> {
            log.info("审核结果监听器已启动");
            
            while (isListening) {
                try {
                    // 从结果队列获取审核结果，使用专门的审核RedisTemplate
                    String auditResultJson = auditRedisTemplate.opsForList().rightPop(RESULT_QUEUE, 1, TimeUnit.SECONDS);

                    if (auditResultJson != null) {
                        log.info("从Redis获取到审核结果: {}", auditResultJson);
                        handleAuditResult(auditResultJson);
                    }
                    
                } catch (Exception e) {
                    log.error("监听审核结果异常: {}", e.getMessage());
                    try {
                        Thread.sleep(1000); // 出错后休息1秒
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
            
            log.info("审核结果监听器已停止");
        });
    }
    
    @Override
    public void stopAuditResultListener() {
        isListening = false;
    }
}
